from google.appengine.ext import db

class NoSuchCollectionError (BaseException): pass

class User (db.Model):
	display_name = db.StringProperty ()
	google_user = db.UserProperty ()
	favourite_views = db.ListProperty (db.Key)
	saved_views = db.ListProperty (db.Key)

	def __unicode__ (self):
		return self.display_name

	@classmethod
	def from_username (self, username):
		q = User.all ()
		q.filter ("display_name =", username)
		r = q.fetch (1)
		if r == []: return None
		return r[0]

class Dataset (db.Model):
	name = db.StringProperty ()
	start = db.DateTimeProperty ()
	end = db.DateTimeProperty ()
	filename = db.StringProperty ()
	created = db.DateTimeProperty ()
	x_units = db.StringProperty ()
	y_units = db.StringProperty ()
	author = db.ReferenceProperty (User)
	source = db.StringProperty ()
	source_url = db.StringProperty ()
	source_article = db.StringProperty ()
	source_section = db.StringProperty ()
	source_table = db.StringProperty ()
	pub_date = db.DateTimeProperty (auto_now_add=True)
	data_mode = db.StringProperty ()
	tags = db.StringListProperty ()

	def __unicode__ (self):
		return self.name

	@classmethod
	def is_installed (self, filename):
		q = Dataset.all ()
		q.filter ("filename =", filename)
		r = q.fetch (1)
		if r == []: return False
		return True

	def js_start (self):
		return self.start.strftime ("%a, %d %b %Y %H:%M:%S GMT")

	def js_end (self):
		return self.end.strftime ("%a, %d %b %Y %H:%M:%S GMT")

class Collection (db.Model):
	name = db.StringProperty ()
	pub_date = db.DateTimeProperty (auto_now_add=True)
	author = db.ReferenceProperty (User)
	charts = db.ListProperty (db.Key)
	published = db.BooleanProperty ()
	slug = db.StringProperty ()

	def __unicode__ (self):
		return self.name

	@classmethod
	def from_slug (self, slug):
		colls = Collection.all ()
		colls.filter ("slug =", slug)
		colls.fetch(1)
		if not len(colls)>0:
			raise NoSuchCollectionError ()
		return colls[0]

class Annotation (db.Model):
	author = db.ReferenceProperty (User)
	title = db.StringProperty ()
	content = db.StringProperty (multiline=True)
	pub_date = db.DateTimeProperty (auto_now_add=True)
	date = db.DateTimeProperty ()
	published = db.BooleanProperty ()
	short_description = db.StringProperty ()
	dataset = db.ReferenceProperty (Dataset)

	@classmethod
	def get_annotations (cls, start_date=None, end_date=None, user=None, dataset=None, limit=100, published=True):
		query = Annotation.all ()
		if dataset: query.filter ('dataset =', dataset)
		if user: query.filter ('author =', user)
		if start_date: query.filter ('date >', start_date)
		if end_date: query.filter ('date <', end_date)
		if published: query.filter ('published =', True)
		return query.fetch (limit)

	def __unicode__ (self):
		return self.title

class Tag (db.Model):
	name = db.StringProperty ()

class TagMembership (db.Model):
	tag = db.ReferenceProperty (Tag)
	annotation = db.ReferenceProperty (Annotation)

class ChartView (db.Model):
	name = db.StringProperty ()
	datasets = db.ListProperty (db.Key)
	author = db.ReferenceProperty (User)
	creation_date = db.DateTimeProperty (auto_now_add=True)
	start_date = db.DateTimeProperty ()
	end_date = db.DateTimeProperty ()
	published = db.BooleanProperty ()
	saved = db.BooleanProperty ()

	def __unicode__ (self):
		if self.name: return self.name
		return str(self.key())

	@classmethod
	def get_views (cls, user=None, saved=True, limit=20):
		query = ChartView.all ()
		if user: query.filter ('author =', user)
		if saved: query.filter ('saved =', True)
		return query.fetch (limit)

	def iso_start (self):
		return self.start_date.strftime ("%Y-%m-%d")

	def iso_end (self):
		return self.end_date.strftime ("%Y-%m-%d")

